package com.example.demo.core.model;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.util.TypeUtils;
import com.example.demo.core.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author yj
 * @date 2021-08-22 11:23
 */
@Slf4j
public class BaseMap<K, V> extends HashMap<K, V> implements Serializable {


    public BaseMap() {
        super(16);
    }

    public BaseMap(int initialCapacity) {
        super(initialCapacity);
    }

    public BaseMap(int initialCapacity, float loadFactor) {
        super(initialCapacity, loadFactor);
    }

    public String toJson() {
        return JsonUtil.toJson(this);
    }

    public <T> T toObject(Class<T> clazz) {
        return TypeUtils.castToJavaBean(this, clazz);
    }

    public <T> T toObject(TypeReference<T> typeReference) {
        return TypeUtils.cast(this, typeReference.getType(), ParserConfig.getGlobalInstance());
    }

    public BaseMap<K, V> getMap(K key) {
        V value = get(key);
        return JsonUtil.jsonObjectToType(value, new TypeReference<BaseMap<K, V>>() {
        });
    }

    public <T> List<T> getList(K key) {
        V value = get(key);
        return JsonUtil.jsonObjectToType(value, new TypeReference<List<T>>() {
        });
    }

    public <T> T getObject(K key, Class<T> clazz) {
        V obj = get(key);
        return TypeUtils.castToJavaBean(obj, clazz);
    }

    public <T> T getObject(K key, Type type) {
        V obj = get(key);
        return TypeUtils.cast(obj, type, ParserConfig.getGlobalInstance());
    }

    public <T> T getObject(K key, TypeReference<T> typeReference) {
        V obj = get(key);
        return TypeUtils.cast(obj, typeReference.getType(), ParserConfig.getGlobalInstance());
    }

    public Boolean getBoolean(K key) {
        V value = this.get(key);
        return value == null ? null : TypeUtils.castToBoolean(value);
    }

    public byte[] getBytes(K key) {
        V value = this.get(key);
        return value == null ? null : TypeUtils.castToBytes(value);
    }

    public boolean getBooleanValue(K key) {
        V value = this.get(key);
        Boolean booleanVal = TypeUtils.castToBoolean(value);
        return booleanVal != null && booleanVal;
    }

    public Byte getByte(K key) {
        V value = this.get(key);
        return TypeUtils.castToByte(value);
    }

    public byte getByteValue(K key) {
        V value = this.get(key);
        Byte byteVal = TypeUtils.castToByte(value);
        return byteVal == null ? 0 : byteVal;
    }

    public Short getShort(K key) {
        V value = this.get(key);
        return TypeUtils.castToShort(value);
    }

    public short getShortValue(K key) {
        V value = this.get(key);
        Short shortVal = TypeUtils.castToShort(value);
        return shortVal == null ? 0 : shortVal;
    }

    public Integer getInteger(K key) {
        V value = this.get(key);
        return TypeUtils.castToInt(value);
    }

    public int getIntValue(K key) {
        V value = this.get(key);
        Integer intVal = TypeUtils.castToInt(value);
        return intVal == null ? 0 : intVal;
    }

    public Long getLong(K key) {
        V value = this.get(key);
        return TypeUtils.castToLong(value);
    }

    public long getLongValue(K key) {
        V value = this.get(key);
        Long longVal = TypeUtils.castToLong(value);
        return longVal == null ? 0L : longVal;
    }

    public Float getFloat(K key) {
        V value = this.get(key);
        return TypeUtils.castToFloat(value);
    }

    public float getFloatValue(K key) {
        V value = this.get(key);
        Float floatValue = TypeUtils.castToFloat(value);
        return floatValue == null ? 0.0F : floatValue;
    }

    public Double getDouble(K key) {
        V value = this.get(key);
        return TypeUtils.castToDouble(value);
    }

    public double getDoubleValue(K key) {
        V value = this.get(key);
        Double doubleValue = TypeUtils.castToDouble(value);
        return doubleValue == null ? 0.0D : doubleValue;
    }

    public BigDecimal getBigDecimal(K key) {
        V value = this.get(key);
        return TypeUtils.castToBigDecimal(value);
    }

    public BigInteger getBigInteger(K key) {
        V value = this.get(key);
        return TypeUtils.castToBigInteger(value);
    }

    public String getString(K key) {
        V value = this.get(key);
        return value == null ? null : value.toString();
    }

    public Date getDate(K key) {
        V value = this.get(key);
        return TypeUtils.castToDate(value);
    }

    public java.sql.Date getSqlDate(K key) {
        V value = this.get(key);
        return TypeUtils.castToSqlDate(value);
    }

    public Timestamp getTimestamp(K key) {
        V value = this.get(key);
        return TypeUtils.castToTimestamp(value);
    }

    public static void main(String[] args) {
        JSONObject jsonObject = new JSONObject();
    }

}
